import {Set, Map} from "immutable";
import {Resource, resourceKey} from './resource'

type Entity = new () => any

export class Resolver {

  entities = Set<Entity>();

  resources = (() => {
    let entities: Set<Entity>;
    let resources: Map<string, Resource>;

    const refresh = () => {
      if (!entities || !entities.equals(this.entities)) {
        entities = this.entities;
        resources = Map();
        entities.forEach((entity) => {
          resources = resources.set(entity.name, Reflect.getMetadata(resourceKey, entity))
        })
      }
    };

    return {
      all: () => {
        refresh();
        return resources.toList().toArray()
      },
      get: (entityName: string) => {
        refresh();
        return resources.get(entityName) as Resource;
      }
    }
  })();

  register(entities: Entity[]) {
    entities.forEach(entity => {
      this.entities = this.entities.add(entity);
    });
  }

  toSchema() {
    return {
      // plugins: this.plugins.map(plugin => plugin.toConfig()),
      resources: this.resources.all().map(resource => resource.toConfig())
    }
  }

  group(entityName: string, queries: object) {
    const resource = this.resources.get(entityName);
    return resource.group(queries);
  }

  find(entityName: string, queries: object) {
    const resource = this.resources.get(entityName);
    return resource.find(queries);
  }

  findById(entityName: string, queries: object) {
    const resource = this.resources.get(entityName);
    return resource.findById(queries);
  }

  save(entityName: string, queries: object) {
    const resource = this.resources.get(entityName);
    return resource.save(queries);
  }

  delete(entityName: string, queries: object) {
    const resource = this.resources.get(entityName);
    return resource.delete(queries);
  }

}
